<template>
  <video
    ref="videoRef"
    :controls="controls"
    :style="style"
    :poster="poster"
    :autoplay="autoplay"
    :muted="muted"
    :loop="loop"
    :width="width"
    :height="height"
    :preload="preload"
    @play="$emit('play', $event)"
    @pause="$emit('pause', $event)"
    @ended="$emit('ended', $event)"
    @error="$emit('error', $event)"
  ></video>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, watch } from "vue";
import Hls from "hls.js";

const props = defineProps({
  src: { type: String, required: true },
  controls: { type: Boolean, default: true },
  poster: String,
  autoplay: { type: Boolean, default: false },
  muted: { type: Boolean, default: false },
  loop: { type: Boolean, default: false },
  width: [String, Number],
  height: [String, Number],
  style: [String, Object],
  preload: { type: String, default: 'metadata' },
});

const videoRef = ref(null);
let hls = null;

const setupVideo = () => {
  if (!videoRef.value) return;
  // 先清理旧的 hls 实例和 src
  if (hls) {
    hls.destroy();
    hls = null;
  }
  videoRef.value.src = '';

  if (props.src && props.src.endsWith(".m3u8")) {
    if (Hls.isSupported()) {
      hls = new Hls({
        maxBufferLength: 30,
        maxMaxBufferLength: 60,
        liveSyncDuration: 10,
      });
      hls.on(Hls.Events.ERROR, (event, data) => {
        if (data.fatal) {
          // 发生致命错误时，尝试销毁并回退到原生 video
          hls.destroy();
          hls = null;
          videoRef.value.src = props.src;
        }
      });
      hls.loadSource(props.src);
      hls.attachMedia(videoRef.value);
    } else if (videoRef.value.canPlayType("application/vnd.apple.mpegurl")) {
      videoRef.value.src = props.src;
    }
  } else {
    videoRef.value.src = props.src;
  }
};

onMounted(setupVideo);
onBeforeUnmount(() => {
  if (hls) {
    hls.destroy();
    hls = null;
  }
  if (videoRef.value) {
    videoRef.value.src = '';
  }
});
watch(() => props.src, setupVideo);
</script>

<script>
export default {
  name: "HlsVideo",
};
</script>
